<html>
<head><meta charset="utf-8"><title>About SVE&#x27;s model · project-portable-simd · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/index.html">project-portable-simd</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html">About SVE&#x27;s model</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="212190181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212190181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212190181">(Oct 03 2020 at 21:13)</a>:</h4>
<p>Having reviewed the major SIMD ISAs, I think the one that makes the most sense to me is the Neon architecture for v8 ARM. Not surprising that it is more coherent, since it's more recent, but in particular the yet-more-recent SVE (mostly for HPC) basically has you model everything as 128-bit vectors, so you can have any type within that framework as long as it's expressed as <code>[[VectorBits; 128]; N]</code>.</p>
<p>So I realize this will probably be taken as a jokepost (I'm not sure how serious I am myself), but: why not tho'?<br>
Why <em>not</em> have larger SIMD arrays expressed as 128-bit vector types and just break a larger vector type into array segments?<br>
I expect there's a good reason, like not having atomicity promises, but we're going to have trouble upholding atomicity promises across architectures anyways.</p>



<a name="212190327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212190327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212190327">(Oct 03 2020 at 21:17)</a>:</h4>
<p>Well, doesn't repr(simd) require every type to be a single tuple struct?  Also the alignment will be different</p>



<a name="212190667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212190667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212190667">(Oct 03 2020 at 21:27)</a>:</h4>
<blockquote>
<p>The simd repr can be attached to a struct and will cause such a struct to be compiled to a SIMD vector. It can be generic, but it is required that any fully monomorphised instance of the type consist of only a single "primitive" type, repeated some number of times.</p>
<p>Adding repr(simd) to a type may increase its minimum/preferred alignment, based on platform behaviour. (E.g. x86 wants its 128-bit SSE vectors to be 128-bit aligned.)<br>
--<strong><a href="https://rust-lang.github.io/rfcs/1199-simd-infrastructure.html">RFC 1199: SIMD Infrastructure</a></strong></p>
</blockquote>



<a name="212191851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212191851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212191851">(Oct 03 2020 at 22:00)</a>:</h4>
<p>I am not sure that actually says anything to affirm or refute, I just thought it was interesting to dig up.<br>
repr(simd) requires "machine types", and does require a tuple struct, but I'm not sure that is actually a requirement of implementation as opposed to just incidental. I am tempted to ask.</p>



<a name="212191884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212191884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212191884">(Oct 03 2020 at 22:01)</a>:</h4>
<p>hmm. OK, it would require a new way of defining a type in order to implement, currently. Blah.</p>



<a name="212192346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212192346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212192346">(Oct 03 2020 at 22:14)</a>:</h4>
<p>So:<br>
GOOD ANSWER!</p>



<a name="212192473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212192473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212192473">(Oct 03 2020 at 22:18)</a>:</h4>
<p>defining a very long tuple struct is Actually a Pain though.</p>



<a name="212192486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212192486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212192486">(Oct 03 2020 at 22:19)</a>:</h4>
<p>u8x64 <span aria-label="grimacing" class="emoji emoji-1f62c" role="img" title="grimacing">:grimacing:</span></p>



<a name="212197581"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212197581" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212197581">(Oct 04 2020 at 00:34)</a>:</h4>
<p>It is. The macro I wrote for defining them is somewhat clean but still not great</p>



<a name="212197587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212197587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212197587">(Oct 04 2020 at 00:35)</a>:</h4>
<p>Readable but feels unnecessary?</p>



<a name="212230735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212230735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212230735">(Oct 04 2020 at 16:48)</a>:</h4>
<p><span class="user-mention" data-user-id="281757">@Jubilee</span> Some vector operations can be broken into 128-bit components, and some can't be. Some operations are inherently a specific width and can't be decomposed into just twice as many operations on vectors half the width.</p>



<a name="212230741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212230741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212230741">(Oct 04 2020 at 16:48)</a>:</h4>
<p>For example, shuffle or selection operations are inherently the full width of the vector they're operating on.</p>



<a name="212233508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212233508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212233508">(Oct 04 2020 at 17:55)</a>:</h4>
<p>Actually... a number of the vendor shuffles are specifically <em>not</em> shuffling among the full width of the register.</p>



<a name="212233721"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212233721" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212233721">(Oct 04 2020 at 17:59)</a>:</h4>
<p>Does anyone other than Intel do that? But I agree shuffling across halves of registers is not universal</p>



<a name="212233985"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212233985" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212233985">(Oct 04 2020 at 18:04)</a>:</h4>
<p>I'm only really familiar with the intel case. ARM/Neon isn't in stable rust so I haven't ever super looked into it.</p>



<a name="212234026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212234026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Caleb Zulawski <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212234026">(Oct 04 2020 at 18:05)</a>:</h4>
<p>I'm not particularly familiar with NEON either but my understanding is it doesn't really have shuffles, it has table lookups and otherwise uses standard loads and stores (though I could be wrong?)</p>



<a name="212235806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212235806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212235806">(Oct 04 2020 at 18:44)</a>:</h4>
<p>Libre-SOC's SimpleV is planned to support shuffles that operate within 1, 2, 3, or 4 element subvectors, since the hardware can implement those more efficiently. We may also allow combining those shuffles with other operations in the same instruction e.g. fadd and shuffle or load and shuffle.</p>



<a name="212336162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212336162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212336162">(Oct 05 2020 at 18:11)</a>:</h4>
<p>okay, so shuffling in a 4 element subvector means a 256-bit "hard vector" would be required if you're allowed to shuffle 4 u64s</p>



<a name="212336613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212336613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212336613">(Oct 05 2020 at 18:15)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> what's the widest shuffling action that Intel allows?<br>
<span class="user-mention" data-user-id="312331">@Caleb Zulawski</span> This is a reasonable summary of what Arm permits for permutations, basically they optimize for a limited set of "shuffle-like" (permutation) operations (you could think of it as "they special cased common shuffles and then let everything else be table lookups"). <a href="https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/coding-for-neon---part-5-rearranging-vectors">https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/coding-for-neon---part-5-rearranging-vectors</a></p>



<a name="212337232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337232">(Oct 05 2020 at 18:20)</a>:</h4>
<p><span class="user-mention" data-user-id="281757">@Jubilee</span> There are both lane-crossing and non-lane-crossing shuffles. The widest shuffle I know of is "shuffle 16-bit values from two 512-bit registers into one of those two 512-bit registers".</p>



<a name="212337328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337328">(Oct 05 2020 at 18:21)</a>:</h4>
<p>interesting.</p>



<a name="212337359"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337359" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337359">(Oct 05 2020 at 18:21)</a>:</h4>
<p><a href="https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd">https://www.felixcloutier.com/x86/vpermt2w:vpermt2d:vpermt2q:vpermt2ps:vpermt2pd</a></p>



<a name="212337493"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337493" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337493">(Oct 05 2020 at 18:22)</a>:</h4>
<p>The non-lane-crossing shuffles are more like "shuffle bytes within 128-bit lanes of a 256-bit or 512-bit register".</p>



<a name="212337644"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337644" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337644">(Oct 05 2020 at 18:23)</a>:</h4>
<p><del>okay but does the portable API have to support that</del><br>
I think this conversation actually turned up a more interesting complaint that I'm genuinely more concerned about: instantiating a <code>u8x64</code> as a tuple struct is hellish and nonsensical since that's what array APIs are for.</p>



<a name="212337697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337697">(Oct 05 2020 at 18:24)</a>:</h4>
<p><a href="https://docs.rs/safe_arch/0.5.2/safe_arch/?search=shuffle">https://docs.rs/safe_arch/0.5.2/safe_arch/?search=shuffle</a></p>
<p>doesn't cover 512-bit ops, but does make it like 5% more understandable</p>



<a name="212337853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212337853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212337853">(Oct 05 2020 at 18:25)</a>:</h4>
<p>aside from "it wasn't ready for prime time yet at the time it was first implemented", what <em>are</em> the reasons to not treat SIMD types as an exotic case of arrays, instead of an exotic case of tuples?</p>



<a name="212338016"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212338016" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212338016">(Oct 05 2020 at 18:26)</a>:</h4>
<p>We've got alignment concerns, but repr(simd) has a CYA clause in "repr(simd) is allowed to change alignment however it wants, nyeh".</p>



<a name="212361550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212361550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212361550">(Oct 05 2020 at 21:55)</a>:</h4>
<p>i do think 128bit vectors are at a sweet spot for versatility/usefulness, and in truth I'd have no trouble saying that they're probably the most important vector size (and have been for some time). ARM's work here is quite impressive, too. But i don't think we should limit the API in ways that make wider vectors less viable.</p>
<p>perhaps the ARM approach will win out (I hope so) but I suspect eventually vectors will just get wider and wider — we saw this with GPUs. (And hell, isn't riscv doing some arbitrary width stuff? — i hesitate to even mention this, since it sounds so painful to work with and might be vaporware, but yeah, it shows that the hardware designers there went through a lot of pain to avoid assumptions around width)</p>
<p>More broadly (and at the risk of stating the obvious): i strongly feel we need to avoid an API that LLVM will have trouble turning into the same instructions you'd write by hand. i think it would be a huge failure if high perf. code has to continue using direct intrinsics (after all, you probably wouldn't dip into SIMD types if you aren't already trying to get the most out of your hardware).</p>
<p>The goal (IMO) should be that we can a claim that it's as good as you can write by hand (similar to how async/await makes this claim — and I think we're in an easier position than the async folks were). i suspect an underlying model of [vec128; N] would hurt this (despite the fact that i'd say 128bit vecs are the most important vector type and have been for a while)</p>
<blockquote>
<p>I think this conversation actually turned up a more interesting complaint that I'm genuinely more concerned about: instantiating a u8x64 as a tuple struct is hellish and nonsensical since that's what array APIs are for.</p>
</blockquote>
<p>Worth noting that this is a problem for smaller vectors too. e.g. in some code i wrote a while ago, i have:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[rustfmt::skip]</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">thresholds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_mm_setr_epi8</span><span class="p">(</span><span class="w"></span>
<span class="w">    </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="mh">0xc2</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="mh">0xe1</span><span class="p">,</span><span class="w"> </span><span class="mh">0xf1</span><span class="p">,</span><span class="w"></span>
<span class="p">);</span><span class="w"></span>
</code></pre></div>

<p>which isn't great, but honestly its really not meaningfully different than a lookup table, which would require a similar rustfmt directive.</p>
<p>i think the common case for big vectors of bytes is loading them out of a slice anyway. i don't think this is a good argument to not support wider vectors (not that i'm saying i think anyone is making this argument).</p>



<a name="212361976"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212361976" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212361976">(Oct 05 2020 at 22:00)</a>:</h4>
<p>you can programmatically const-specify arrays.</p>



<a name="212362989"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212362989" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212362989">(Oct 05 2020 at 22:12)</a>:</h4>
<p>Side note:</p>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/257879-project-portable-simd/topic/About.20SVE's.20model/near/212361550">said</a>:</p>
<blockquote>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[rustfmt::skip]</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">thresholds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_mm_setr_epi8</span><span class="p">(</span><span class="w"></span>
<span class="w">    </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="mh">0xc2</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">128</span><span class="p">,</span><span class="w"> </span><span class="mh">0xe1</span><span class="p">,</span><span class="w"> </span><span class="mh">0xf1</span><span class="p">,</span><span class="w"></span>
<span class="p">);</span><span class="w"></span>
</code></pre></div>

</blockquote>
<p>We should really teach rustfmt to handle certain patterns better, so that the skip isn't necessary.</p>



<a name="212364346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212364346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212364346">(Oct 05 2020 at 22:28)</a>:</h4>
<p>there's some stuff to make certain code more compact, but it's not on by default and i think some of it's also nightly only.</p>



<a name="212375960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212375960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212375960">(Oct 06 2020 at 01:33)</a>:</h4>
<p>basically, what you can do there with const-eval rn would be something like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">const</span><span class="w"> </span><span class="n">ARRAY</span>: <span class="p">[</span><span class="kt">i8</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">arr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="mi">128</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">];</span><span class="w"></span>
<span class="w">  </span><span class="n">arr</span><span class="p">[</span><span class="mi">12</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">62</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="n">arr</span><span class="p">[</span><span class="mi">14</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">31</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="n">arr</span><span class="p">[</span><span class="mi">15</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">15</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="n">arr</span><span class="w"></span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>

<p>Which, OK, that's not great itself, but then converting from array -&gt; SIMD type, that's slightly better than manually specifying, especially in, say, the 256-bit vector case.</p>



<a name="212376141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212376141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212376141">(Oct 06 2020 at 01:36)</a>:</h4>
<p>re: arbitrary width, <span class="user-mention" data-user-id="209168">@Thom Chiovoloni</span>, RISCV-V (the vector ISA for RISCV) is akin to SVE in all regards: it uses 2^n widths and the actual vector width is literally hard-wired, but the lengths are dynamic from the perspective of the language handling them (which requires the same tricks re: stack awareness that SVE has, but also leads to the same implications re: "well, it's arbitrary, but only so-so.")</p>



<a name="212378816"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212378816" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212378816">(Oct 06 2020 at 02:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="281757">Jubilee</span> <a href="#narrow/stream/257879-project-portable-simd/topic/About.20SVE's.20model/near/212376141">said</a>:</p>
<blockquote>
<p>re: arbitrary width, <span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span>, RISCV-V (the vector ISA for RISCV) is akin to SVE in all regards: it uses 2^n widths and the actual vector width is literally hard-wired, but the lengths are dynamic from the perspective of the language handling them (which requires the same tricks re: stack awareness that SVE has, but also leads to the same implications re: "well, it's arbitrary, but only so-so.")</p>
</blockquote>
<p>That's not quite true: RISC-V V has registers that are fixed-size at the CPU level, each different CPU can define a different fixed size. However, at least last time I read the spec, RISC-V V allows operations to operate on any arbitrary-length not bigger than the register length, where the length is dynamically selectable by using the <code>setvl</code> instruction to set the Vector Length register. IIRC Arm SVE only supports operations at 128-bit (for NEON) and the full HW register size, not any arbitrary dynamically selectable length.</p>
<p>Libre-SOC's SimpleV is more similar to RISC-V V since it also supports arbitrary dynamically-selectable lengths using a VL register, though the vectors are mapped to registers differently.</p>



<a name="212378904"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212378904" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212378904">(Oct 06 2020 at 02:38)</a>:</h4>
<p>Hmm, it is entirely possible I misunderstood the RISCV-V spec! I should note they leaned towards firming up some things in their last versioning pass though on the general reasoning of "less overall variation =&gt; easier to implement an already reasonably challenging design."</p>



<a name="212379297"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212379297" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212379297">(Oct 06 2020 at 02:46)</a>:</h4>
<p>It's entirely possible it changed dramatically since I last read it, which was about a year ago.</p>



<a name="212382639"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212382639" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212382639">(Oct 06 2020 at 04:03)</a>:</h4>
<p><span class="user-mention" data-user-id="229517">@Jacob Lifshay</span> <br>
Here's the relevant segment:</p>
<blockquote>
<p>3.4. Vector Length Register vl</p>
<p>The XLEN-bit-wide read-only vl CSR can only be updated by the vsetvli and vsetvl instructions, and the fault-only-first vector load instruction variants.</p>
<p>The vl register holds an unsigned integer specifying the number of elements to be updated by a vector instruction. Elements in any destination vector register group with indices ≥ vl are unmodified during execution of a vector instruction. When vstart ≥ vl, no elements are updated in any destination vector register group.<br>
Note: As a consequence, when vl=0, no elements are updated in the destination vector register group, regardless of vstart.<br>
Note: Instructions that write a scalar integer or floating-point register do so even when vstart ≥ vl.<br>
Note: The number of bits implemented in vl depends on the implementation’s maximum vector length of the smallest supported type. The smallest vector implementation, RV32IV, would need at least six bits in vl to hold the values 0-32 (with VLEN=32, LMUL=8 and SEW=8 results in VLMAX of 32).</p>
</blockquote>



<a name="212383590"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/257879-project-portable-simd/topic/About%20SVE%27s%20model/near/212383590" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/257879-project-portable-simd/topic/About.20SVE&#x27;s.20model.html#212383590">(Oct 06 2020 at 04:24)</a>:</h4>
<p>yeah, so it hasn't changed that much</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>